/*!
 * 文件名称： bsp_rtc.c
 * 描    述： rtc 驱动文件
 * 版本：     2023-12-03, V1.0
*/

/*
* GD32F303东方红开发板V1.0
* 淘宝商城：   https://juwo.taobao.com
* 技术交流：   https://www.gd32bbs.com/ask/
* 视频学习：   https://space.bilibili.com/475462605
* 微信公众号： gd32bbs
* Copyright    苏州聚沃电子科技有限公司
* 版权所有，盗版必究。
*/

#include "bsp_rtc.h"
#include "driver_rtc.h"
#include "driver_public.h"

/* enter the second interruption,set the second interrupt flag to 1 */
__IO uint32_t timedisplay;

const uint8_t month_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
typedef struct
{
    uint16_t years;
    uint8_t months;
    uint8_t days;
    uint8_t hours;
    uint8_t minutes;
    uint8_t seconds;
}RTC_Calendar;

RTC_Calendar calendar;

/*!
* 说明     判断是否为闰年函数
* 输入[1]  year：年份
* 返回值   0 ：非闰年
*          1 ：闰年
*/
uint8_t is_leap_year(uint16_t year)
{
    if((year%4 == 0 && year % 100 != 0) || (year % 400 == 0)){
        return 1;
    }else{
        return 0;
    }
}

/*!
* 说明     rtc时间设置函数
* 输入[1]  year：  年
* 输入[2]  month： 月
* 输入[3]  day：   日
* 输入[4]  hour：  时
* 输入[5]  minute：分
* 输入[6]  second：秒
* 返回值   0 ：设置正确
*          1 ：设置错误
*/
uint32_t rtc_time_set(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
{
    uint16_t t;
    uint32_t seccount = 0;
        if (bkp_read_data(BKP_DATA_0) != 0xA5A5)
        {
            rtc_configuration();
            
            if(year < 1970 || year > 2099)
                    return 1;

            for(t = 1970; t < year; t++){
                    if(is_leap_year(t)){
                            seccount += 31622400;
                    }else{
                            seccount += 31536000;
                    }
            }
            month -= 1;
            
            for(t=0; t < month; t++){
                    seccount += (uint32_t)month_table[t] * 86400; 
                    if(is_leap_year(year) && t==1){
                            seccount+=86400;
                    }
            }            
            seccount += (uint32_t)(day-1) * 86400;
            seccount += (uint32_t)hour * 3600;
            seccount += (uint32_t)minute * 60;
            seccount += second;
            rtc_counter_set(seccount);
            bkp_write_data(BKP_DATA_0, 0xA5A5);
            return 0;
        }
        else
        {
            if (rcu_flag_get(RCU_FLAG_PORRST) != RESET){
                    printf_log("Power On Reset occurred....\r\n");
            }else if (rcu_flag_get(RCU_FLAG_EPRST) != RESET){
                    printf_log("External Reset occurred....\r\n");
            }
            rcu_all_reset_flag_clear();

            rcu_periph_clock_enable(RCU_PMU);
            pmu_backup_write_enable();
            rtc_register_sync_wait();
            rtc_interrupt_enable(RTC_INT_SECOND);
            rtc_lwoff_wait();
            return 0;
        }
}

/*!
* 说明     rtc时间显示函数，通过串口打印
* 输入     timevar：RTC计数值
* 返回值   无
*/
void rtc_time_display(uint32_t timevar)
{ 
    static uint16_t daycnt = 0;
    uint32_t temp = 0;
    uint16_t temp1 = 0;
    temp = timevar / 86400;

    if(daycnt != temp) {
        daycnt = temp;
        temp1 = 1970;
        
        while(temp >= 365){
            if(is_leap_year(temp1)){
                if(temp >= 366)
                    temp-=366;
                else 
                    break;
            }else 
                temp -= 365;
            temp1++;
        }
        
        calendar.years = temp1;
        temp1=0;
        
        while(temp >= 28)
        {
            if(is_leap_year(calendar.years) && temp1 == 1){
                if(temp >= 29)
                    temp -= 29;
                else
                    break;
            }else{
                if(temp >= month_table[temp1])
                    temp -= month_table[temp1];
                else
                    break;
            }
            temp1++;
        }
        calendar.months = temp1 + 1;
        calendar.days = temp + 1;
    }
    
    temp = timevar % 86400;
    calendar.hours = temp / 3600;
    calendar.minutes = (temp % 3600) / 60; 
    calendar.seconds = (temp % 3600) % 60; 

    printf_log("Time: %0.4d-%0.2d-%0.2d,%0.2d:%0.2d:%0.2d\r\n", calendar.years, calendar.months, calendar.days, calendar.hours, calendar.minutes, calendar.seconds);
}
